﻿using System.Collections.Generic;
using Microsoft.VisualStudio.Language.Intellisense;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;

namespace PostscriptTools.Intellisense {
	#region IIntellisenseController

	/// <summary>
	/// Standard implementation of an IIntellisenseController to track the mouse pointer
	/// and initiate quick info sessions
	/// </summary>
	internal class TemplateQuickInfoController : IIntellisenseController {
		#region Private Data Members

		private ITextView _textView;
		private IList<ITextBuffer> _subjectBuffers;
		private TemplateQuickInfoControllerProvider _componentContext;
		private IQuickInfoSession _session;

		#endregion

		#region Constructors

		internal TemplateQuickInfoController(ITextView textView, IList<ITextBuffer> subjectBuffers, TemplateQuickInfoControllerProvider componentContext) {
			_textView = textView;
			_subjectBuffers = subjectBuffers;
			_componentContext = componentContext;
			_textView.MouseHover += this.OnTextViewMouseHover;	// when hovering the mouse, invoke quickinfo 
		}

		#endregion

		#region IIntellisenseController Members

		public void ConnectSubjectBuffer(ITextBuffer subjectBuffer) {
		}

		public void DisconnectSubjectBuffer(ITextBuffer subjectBuffer) {
		}

		public void Detach(ITextView textView) {
			if (_textView == textView) {
				_textView.MouseHover -= this.OnTextViewMouseHover;
				_textView = null;
			}
		}

		#endregion

		#region Event Handlers

		private void OnTextViewMouseHover(object sender, MouseHoverEventArgs e) {
			SnapshotPoint? point = this.GetMousePosition(new SnapshotPoint(_textView.TextSnapshot, e.Position));

			if (point != null) {
				ITrackingPoint triggerPoint = point.Value.Snapshot.CreateTrackingPoint(point.Value.Position, PointTrackingMode.Positive);
				// Find the broker for this buffer
				if (!_componentContext.QuickInfoBroker.IsQuickInfoActive(_textView)) {
					_session = _componentContext.QuickInfoBroker.CreateQuickInfoSession(_textView, triggerPoint, true);
					_session.Start();
				}
			}
		}

		#endregion

		#region Private Implementation

		private SnapshotPoint? GetMousePosition(SnapshotPoint topPosition) {
			// Map this point down to the appropriate subject buffer.

			return _textView.BufferGraph.MapDownToFirstMatch(topPosition, PointTrackingMode.Positive, snapshot => _subjectBuffers.Contains(snapshot.TextBuffer), PositionAffinity.Predecessor );
		}

		#endregion
	}

	#endregion
}